查看原文
其他

快速理解 k8s 命名空间

字符串拼接工程师 Go开发大全 2021-08-09

(给Go开发大全加星标)

【导读】Namespace(命名空间)是kubernetes系统中的一个非常重要的概念,本文带你快速准确理解namespace的概念与基本使用。

读完本文你会:

  1. 对k8s中的命名空间(namespace)概念有一个大体上的理解
  2. 了解k8s命名空间基础知识

我们不一上来就讲概念,先打几个简单比方、有一点直觉。

比如有两个孩子都叫Luis,

要把他们互相区分开,要叫他们各自的姓,分别是Perez、Charvez。


他们家族里当然有其他成员,家族成员之间就用英文名字称呼、不互相叫姓了。比如爸爸会管Luis就叫Luis,但是如果他爸爸想要称呼另一个家族里的Luis就要叫姓+名了。同理,如果这个家族之外的人也用姓+名称呼这个家族内的人。

每个家族中都有一定的规矩,规定了谁负责什么东西,每个家族也都有他们可以使用的资源。

说回kubernetes

你可能猜到了,上面说的家族就是kubernetes的命名空间。

每次不指定namespace创建k8s对象时,这个对象就放在“default”命名空间下。

首次创建k8s集群时,k8s会创建一组为内部管理使用的pod和服务,例如:

  • ETCD server
  • 调度器
  • API Server
  • controller manager

上面这些在k8s都是控制面组件

要让k8s用户看不到这些服务,也要能让管理员不对这些服务做误删改,为了达到这个效果,k8s就在创建集群的同时创建一个kube-system命名空间、在这个命名空间下创建控制面组件的服务。

另一个k8s自动创建的命名空间,叫kube-public。这个命名空间里放着所有用户都可见的服务。

如果你的环境很小,就不要弄多命名空间,只用default就可以了。

如果集群规模变大、要在生产环境用上k8s了,你可能要规划起来使用命名空间这件事。

比如,如果想让开发环境和生产环境在同一个k8s集群上,两个环境的资源互相隔离,就可以通过创建两个命名空间达到效果。这样在开发环境操作就不会修改到生产环境的资源了。

每个命名空间都有自己的安全策略和权限。还可以为每个命名空间单独配置quota。

默认命名空间

同一个命名空间下的资源可以用名字互相访问,就和一个家族里的成员互相叫名字一样。

我们看一个图中例子:

前面也提到过,因为这些对象都在一个命名空间下,web app这个pod就可以通过db-service的hostname访问db服务。

mysql.connect("db-service");

如果一个资源想要和其他命名空间下的资源进行通信,就需要在对应服务的名称后加上命名空间的名称才能访问对应的服务。

比如,上面图中的default命名空间内的web-pod,要和dev命名空间内的database服务交互,就要这样写:

mysql.connect("db-service.dev.svc.cluster.local");

服务创建时会生成一个如下图中的dns entry:

相关命令

这条命令是用来列出所有默认命名空间内pod的:

kubectl get pods

要列出某个不是默认命名空间的pod:

kubectl get pods --namespace=[NAMESPACE_NAME]

例子

有pod定义文件如下:

pod-definition.yaml

apiVersion: v1
kind: Pod

metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
    - name: nginx-container
      image: nginx

创建pod对象:

kubectl create -f pod-definition.yaml

使用这个配置文件创建pod、上面的命令也没指定是具体哪个namespace,pod就会被创建到default命名空间里。

要把pod创建到其他命名空间下,要在命令行指定--namespace参数:

kubectl create -f pod-definition.yaml --namespace=dev

如果不想在命令行加参数指定pod创建的命名空间、也要让pod创建到dev环境中,把配置修改如下:

apiVersion: v1
kind: Pod

metadata:
  name: myapp-pod
  namespace: dev  #New

  labels:
    app: myapp
    type: front-end
spec:
  containers:
    - name: nginx-container
      image: nginx

这个配置方法可以保证每次pod都在特定的命名空间下创建。

创建命名空间

创建k8s命名空间有集中方法。

  1. 用命名空间定义文件生成namespace

namespace-dev.yaml文件:

apiVersion: v1
kind: Namespace
metadata:
  name: dev

执行命令:

kubectl create -f namespace-dev.yaml
  1. 不使用YAML文件创建namespace
kubectl create namespace dev

要从default命名空间切换到其他命名空间,执行下列命令:

kubectl config set-context $(kubectl config current-context) --namespace=dev

上面的命令通过修改kubeconfig文件达到切换当前命名空间。

最后看所有命名空间内的pod:

kubectl get pods --all-namespaces

这个命令列出所有命名空间内的所有pod。

限制命名空间的资源

要限制一个命名空间内的资源,要写一个资源的quota定义文件,写明你想要让这些配置在哪个命名空间内生效这些配置:

compute-quota.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: dev

spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: 5Gi
    limits.cpu: "10"
    limits.memory: 10Gi

你可以根据你的需求修改配置文件。

创建quota对象:

kubectl create -f compute-quota.yaml

 - EOF -


推荐阅读(点击标题可打开)

1、Go 竞态检测器 race

2、Go 程序是如何编译成目标机器码的

3、Kubernetes 滚动发布和回滚入门实战


Go 开发大全

参与维护一个非常全面的Go开源技术资源库。日常分享 Go, 云原生、k8s、Docker和微服务方面的技术文章和行业动态。

关注后获取

回复 Go 获取6万star的Go资源库



分享、点赞和在看

支持我们分享更多好文章,谢谢!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存